home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekikoh Dennoh Club 1
/
Gekikoh Dennoh Club Vol. 1 (Japan).7z
/
Gekikoh Dennoh Club Vol. 1 (Japan) (Track 1).bin
/
kowin
/
archive
/
kob
/
kob001s.lzh
/
xbmath.has
< prev
next >
Wrap
Text File
|
1996-09-02
|
38KB
|
2,340 lines
*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
*
* xbmath.has …… ぺけ-BASICの数式評価(コンパイラ)
*
*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
.xref ko_debug
.xref ko_dec_print
.xref ko_hex_print
.include fefunc.h
.include variable.h
.xref hash
.xref first_check_a5_in_line
.xref error
.xref errors
.text
.even
* 他の変数名と重なってないかどうか
* d4.l = * (hash.w)(文字数-1)
* a2.l = 元の対象の開始アドレス
.xdef variable_check
variable_check:
* 重なってない d2.l = -1
* int の n 番と一致 d2.l = n+0000 ( n < システム変数 )
* str の n 番と一致 d2.l = n+0100 ( n < システム変数 )
* char の n 番と一致 d2.l = n+0200
* float の n 番と一致 d2.l = n+8000
* d2.l < 0 = 代入出来ない(当たりがない or system 変数)
* d0 = 0 : 普通の変数
* 1 : 配列 ( a0 = その配列情報のポインタ )
* $80 : auto 変数
* $81 : auto 配列 ( a0 = その配列情報のポインタ )
* -1 : 当たりなし
lea.l system変数,a3
moveq #SYSVARNUM-1,d2 * system変数の個数
sysvar_check_loop:
cmp.l (a3),d4
addq.l #8,a3
scl0:
dbeq d2,sysvar_check_loop
bne scl1
movea.l -8+4(a3),a0
movea.l a2,a1
move.w d4,d1
@@:
cmp.b (a1)+,(a0)+
dbne d1,@b
bne scl0
* 当たり
subq.w #4,d2 * str 型の system変数番号
bcc int_sys_var
cmpi.w #-4,d2 * 'inkey$'
bne 1f
cmpi.b #'(',(a5)
bne @f
addq.l #1,a5
bsr first_check_a5_in_line
cmpi.b #'0',(a5)+
bne 式err
bsr first_check_a5_in_line
cmpi.b #')',(a5)+
bne 式err
subq.w #1,d2 * 'inkey$(0)' = -5
@@:
1:
swap d2
move.w #$0100,d2 * str
bra vc_end
int_sys_var:
subi.w #SYSVARNUM-4,d2 * int 型の system変数番号
swap d2
clr.w d2 * int
bra vc_end
scl1:
tst.b d7
bpl global_var_check
moveq #8,d3 * 1項目辺りのサイズ(普通の変数用)
lea.l AUTOint,a3
bsr _check
bge vcA_end
lea.l AUTOstr,a3
bsr _check
bmi @f
move.w #$0100,d2
bra vcA_end
@@:
lea.l AUTOfloat,a3
bsr _check
bmi @f
move.w #$8000,d2
bra vcA_end
@@:
lea.l AUTOchar,a3
bsr _check
bmi @f
move.w #$0200,d2
vcA_end:
move.w #$0080,d0 * auto 変数
rts
@@:
moveq #$20,d3 * 1項目辺りのサイズ(配列用)
tst.b d7
bpl global_var_check
lea.l AUTO配列,a3
bsr _check
bmi global_var_check
move.w 8(a0),d2 * 型
* move.w 12(a0),d1 * 添え字の最大数(1次元目)
move.w #$0081,d0 * auto 配列
rts
global_var_check:
moveq #8,d3 * 1項目辺りのサイズ(普通の変数用)
lea.l 変数int,a3
bsr _check
bge vc_end
lea.l 変数str,a3
bsr _check
bmi @f
move.w #$0100,d2
bra vc_end
@@:
lea.l 変数float,a3
bsr _check
bmi @f
move.w #$8000,d2
bra vc_end
@@:
lea.l 変数char,a3
bsr _check
bmi global_dim_check
move.w #$0200,d2
vc_end:
moveq #0,d0 * 普通の変数
rts
global_dim_check:
moveq #$20,d3 * 1項目辺りのサイズ(配列用)
lea.l 配列,a3
bsr _check
bmi 変数当たりなし
move.w 8(a0),d2 * 型
* move.w 12(a0),d1 * 添え字の最大数
moveq #1,d0 * 配列
rts
変数当たりなし:
moveq #-1,d0 * 当たりなし
rts
* d3 = 1項目辺りのサイズ(普通の変数 = 8 , 配列 = $20 )
_check:
* d2.upper.w = 当たった変数番号 ( -1 = 当たりなし )
movea.l (a3)+,a0
move.w (a3),d2 * 登録されている変数の個数 - 1
bmi _check_path
move.w d2,d0
moveq #変数個数,d5
_check_loop:
cmp.l (a0),d4 * (hash.w)(文字数-1)
bne c_next
movea.l 4(a0),a3
movea.l a2,a1
move.w d4,d1
@@:
cmp.b (a1)+,(a3)+
dbne d1,@b
beq _check_合致
c_next:
adda.w d3,a0
subq.w #1,d5
dbeq d0,_check_loop
bne _check_path
moveq #変数個数,d5
movea.l (a0),a0 * 次の鎖
dbra d0,_check_loop
_check_path:
moveq #-1,d2
rts
_check_合致:
sub.w d0,d2
swap d2
clr.w d2
rts
.xdef sysfunc_check
sysfunc_check:
movem.l d1/d2/d4/a0-a3,-(sp)
movem.l 4+4*7(sp),d4/a2 * hash/name
lea.l system関数,a3
moveq #SYSFUNCNUM-1,d2 * system関数の個数
sysfunc_check_loop:
cmp.l (a3),d4
addq.l #8,a3
sf0:
dbeq d2,sysfunc_check_loop
bne sf1 * 該当無し
movea.l -8+4(a3),a0 * address
movea.l a2,a1
move.w d4,d1 * 長さ-1
@@:
cmp.b (a1)+,(a0)+
dbne d1,@b
bne sf0 * 外れ
* 当たりゆえ登録
lea.l システム関数対応option(pc),a0
add.w d2,d2
move.w (a0,d2.w),d2
* KH ' システム関数番号*4 = ',d2
lea.l system関数登録,a0
move.l a4,(a0,d2.w) * プログラムアドレス登録!
sf1:
movem.l (sp)+,d1/d2/d4/a0-a3
rts
* d4.l = * (hash.w)(文字数-1)
* a2.l = 元の対象の開始アドレス
.xdef function_check
function_check:
* d0.w = ヒットした関数の返り値の型 ( = 0 : 該当関数無し )
* = $8000 float
* = $8001 int
* = $8002 char 新設
* = $8003 str
* = $ffff void
* d0.w < 0 の時
* d1.w = 引き数の個数
* d3.w = 0 から始まる関数番号 ( < 0 : 内部関数 )
* a2 = パラメーターテーブル
move.w 内部関数個数,d5
bmi @f
movea.l 内部関数buf,a3
bsr fncchk_loop
* tst.w d0
beq @f
move.w d5,d3
sub.w 内部関数個数,d3 * 内部関数番号 (<0)
subq.w #1,d3
rts
@@:
lea.l 外部functable,a0
move.l d4,d0
swap d0
clr.w d3
move.b d0,d3
lsl.w #2,d3
add.w d3,a0
move.w (a0)+,d3 * 関数buf からのオフセット
move.w (a0)+,d5 * 個数
bmi fnc無し
movea.l 関数buf,a3
adda.w d3,a3
lsr.w #4,d3
add.w d5,d3
bsr fncchk_loop
sub.w d5,d3 * 関数番号(あれば)
rts
** **
fncchk_loop:
cmp.l (a3),d4
lea.l $10(a3),a3
fncchk_loop0:
dbeq d5,fncchk_loop
bne fnc無し
move.l a2,a0
move.l -$10+4(a3),a1 * 関数名
move.w d4,d0
@@:
cmp.b (a0)+,(a1)+
dbne d0,@b
bne fncchk_loop0
* 当たり!
movea.l -$10+8(a3),a2 * パラメーターテーブル
movea.l a2,a0
moveq #-1,d1
@@:
addq.w #1,d1
move.w (a0)+,d0
bge @b * 関数の返り値(負の値)
cmpi.w #$8080,d0 * 配列拡張
bne 1f
moveq #$f,d0
and.w (a0)+,d0 * (型+) 次元 - 1
add.w d0,d0
lea.l 2+2(a0,d0.w),a0 * 添字指定フラグと次元だけの添字の大きさ飛ばす
bra @b
1:
* subq.w #1,d1 * 引き数の個数
rts
fnc無し:
moveq #0,d0
rts
** ** ** ** ** ** ** **
.xdef system関数table作成
system関数table作成:
lea.l system関数登録,a4
moveq #EVENTNUM-1,d6 * system関数の個数
@@:
clr.l (a4)+ * 登録エリアを NULL で埋める
dbra d6,@b
lea.l system関数,a4
moveq #SYSFUNCNUM-1,d6 * system関数の個数
lea.l システム関数(pc),a5
bra sysvar_loop
.xdef system変数table作成
system変数table作成:
lea.l system変数,a4
moveq #SYSVARNUM-1,d6 * system変数の個数
lea.l システム変数(pc),a5
sysvar_loop:
bsr hash
* a2.l = 元の対象の開始アドレス
* d5.w = ハッシュ値だ。上位バイトもそのままだ
* d4.l = (hash.w)(文字数 - 1)
* d1.b = お次の文字 ( $00 )
move.l d4,(a4)+ * (hash.w)(文字数 - 1)
move.l a2,(a4)+ * 名前
addq.l #1,a5
dbra d6,sysvar_loop
rts
* システム関数追加の際は、ここにイベント番号を加え、
* 下の「システム関数」の名前のところに逆順にして名前を足す
システム関数対応option:
.dc.w 0*4 * open
.dc.w 1*4 * redraw
.dc.w 2*4 * close
.dc.w 5*4 * move
.dc.w 6*4 * resize
.dc.w 7*4 * iconify
.dc.w 10*4 * mouse_switch
.dc.w 11*4 * mouse_move
.dc.w 12*4 * mouse_enter
.dc.w 13*4 * mouse_out
.dc.w 14*4 * key
.dc.w 15*4 * interval
.dc.w 17*4 * user
システム関数:
.dc.b 'Euser',0 *12
.dc.b 'Einterval',0 *11
.dc.b 'Ekey',0 *10
.dc.b 'Emouse_out',0 *9
.dc.b 'Emouse_enter',0 *8
.dc.b 'Emouse_move',0 *7
.dc.b 'Emouse',0 *6
.dc.b 'Eiconify',0 *5
.dc.b 'Eresize',0 *4
.dc.b 'Emove',0 *3
.dc.b 'Eclose',0 *2
.dc.b 'Eredraw',0 *1
.dc.b 'Eopen',0 *0
.dc.b 0
システム変数:
.dc.b 'csrlin',0 * int -1
.dc.b 'errno',0 * int -2
.dc.b 'free',0 * int -3
.dc.b 'pos',0 * int -4
.dc.b 'WINX',0 * -5
.dc.b 'WINY',0
.dc.b 'WINH',0
.dc.b 'WINV',0
.dc.b 'ITIME',0 * -9
.dc.b 'info_x',0 * -10
.dc.b 'info_y',0
.dc.b 'info_h',0
.dc.b 'info_v',0
.dc.b 'info_Rstat',0 * -14
.dc.b 'info_Lstat',0
.dc.b 'info_Lon',0
.dc.b 'info_Loff',0
.dc.b 'info_Ron',0
.dc.b 'info_Roff',0
.dc.b 'info_MoveFlag',0 * -20
.dc.b 'info_KeyCode',0
.dc.b 'info_ShiftStat',0
.dc.b 'info_Counter',0
.dc.b 'info_ComData',0
.dc.b 'info_Buffer',0
.dc.b 'date$',0 * str -1(3)
.dc.b 'day$',0 * str -2
.dc.b 'time$',0 * str -3
.dc.b 'inkey$',0 * str -4(0)
.dc.b 0
.even
** ** ** ** ** ** ** **
* 演算子チェック
* 演算子だったら d0.w = 演算子番号+優先順位
* 違ったら d0.w = 0
* プログラム終了なら d0.w = -1
.xdef cal_check
cal_check:
* まず、空白(9,32)を飛ばして、先頭の文字を見る。
bsr first_check_a5_in_line
* 数字なら d0 = 0
* 行の終わりなら d0 = -1
* その他なら d0 = そのキャラクタ
tst.w d0
ble cal_check_end0
cmpi.b #'/',d0 * 注釈
bne @f
cmpi.b #'*',1(a5)
beq cal_check_end000 * 注釈なら演算子ではない
@@:
lea.l _m1(pc),a0
moveq #8-1,d1
@@:
cmp.b (a0)+,d0
dbeq d1,@b
bne no_simple_cal
add.w d1,d1
move.w _moji1(pc,d1.w),d0
cmpi.w #6*2,d1
bcs cal_check_end
beq smaller
cmpi.b #'=',1(a5)
bne cal_check_end
move.w #$0e0a,d0 * '>='
addq.l #2,a5
rts
smaller:
cmpi.b #'>',1(a5)
beq not_equal
cmpi.b #'=',1(a5)
bne cal_check_end
move.w #$0d0a,d0 * '<='
addq.l #2,a5
rts
not_equal:
move.w #$0a0a,d0 * '<>'
addq.l #2,a5
rts
cal_check_end:
addq.l #1,a5
cal_check_end0:
rts
cal_check_end000:
moveq #0,d0
rts
_moji1:
.dc.w $0101 * '*'
.dc.w $0201 * '/'
.dc.w $0302 * '\'
.dc.w $0504 * '+'
.dc.w $0604 * '-'
.dc.w $090a * '='
.dc.w $0b0a * '<'
.dc.w $0c0a * '>'
_m1:
.dc.b '><=-+\/*'
* 76543210
no_simple_cal:
lea.l _cp_cal(pc),a1
lea.l _cp_calS(pc),a2
moveq #7-1,d1
@@:
bsr one_check
beq @f
addq.l #2,a1
dbra d1,@b
moveq #0,d0
rts
@@:
move.w (a1),d0
rts
_cp_cal:
.dc.w $1112 * 'or'
.dc.w $1011 * 'and'
.dc.w $0403 * 'mod'
.dc.w $0f10 * 'not'
.dc.w $0806 * 'shl'
.dc.w $0706 * 'shr'
.dc.w $1213 * 'xor'
_cp_calS:
.dc.b 'or',0
.dc.b 'and',0
.dc.b 'mod',0
.dc.b 'not',0
.dc.b 'shl',0
.dc.b 'shr',0
.dc.b 'xor',0
.even
* (a2) と a5 からの文字列を見比べる。
* 一致してかつ、後ろが英数字以外 zero
* 不一致 non zero
* a0,d0 : 破壊
* a2 : $00 の後ろ(次の文字列)
.xdef one_check
one_check:
movea.l a5,a0
@@:
move.b (a2)+,d0
beq oc_ok
cmp.b (a0)+,d0
beq @b
@@:
tst.b (a2)+ * 次へ
bne @b
oc_out:
moveq #-1,d0
rts
oc_ok:
move.b (a0),d0
cmpi.b #'$',d0
beq oc_out
cmpi.b #'0',d0
bcs @f
cmpi.b #'9',d0
bls oc_out
cmpi.b #'A',d0
bcs @f
cmpi.b #'Z',d0
bls oc_out
cmpi.b #'_',d0
beq oc_out
cmpi.b #'a',d0
bcs @f
cmpi.b #'z',d0
bls oc_out
@@:
movea.l a0,a5
moveq #0,d0
rts
.xdef int定数get
int定数get:
movem.l d1-d6/a1-a3,-(sp)
lea.l tmp,a3
* 解釈した結果を (a3) からに書き込み、その長さを d0.l に返す
* int d2.w = 0000
moveq #0,d2
bsr math解釈 * math解釈の最適化を利用
* return d6.w = 変数の型
lea.l tmp,a3
cmpi.w #$80_00,(a3)+
bne 式err
move.l (a3)+,d0
movem.l (sp)+,d1-d6/a1-a3
rts
INT equ $0000
STR equ $0100
CHAR equ $0200
FLOAT equ $8000
不明 equ $ffff
* 解釈した結果を (a3) からに書き込み、その長さを d0.l に返す
* int d2.w = 0000
* str d2.w = 0100
* char d2.w = 0200
* float d2.w = 8000
* 型未判明 d2.w = ffff
.xdef math解釈
math解釈:
* return d6.w = 変数の型
* 今のところ一応 'math解釈' の内部では tmp は使わないことになっている
* a4 : 保存
move.l a4,-(sp) * 全然アドレスレジスタが足りない
lea.l -$400(sp),sp * 1 KB のワーク
movea.l sp,a4
move.l a3,$c(a4) * 書き込み先
movea.l a4,a0
movea.l a4,a1
lea.l $10(a0),a0
move.l a0,(a1)+ * 式を並べるポインタ
lea.l $100-$10(a0),a0
move.l a0,(a1)+ * 項のアドレスを並べるポインタ
lea.l $200-$100(a0),a0
move.l a0,(a1)+ * 項を並べるポインタ
move.l d2,-(sp) * 最後に型チェック
* 式を解釈して (a3) から書き込む
解釈:
* 演算子チェック not と - は特別に先頭に有っても良いので
bsr cal_check
* 演算子だったら d0.w = 演算子番号+優先順位
* 違ったら d0.w = 0
* プログラム終了なら d0.w = -1
tst.w d0
bmi 式err
beq 解釈loop
cmpi.w #$0504,d0 * '+' は 無視
beq 解釈loop
cmpi.w #$0f10,d0 * 'not'
beq Not
cmpi.w #$0604,d0 * '-'
bne 式err * 式の先頭に -,not 以外は使えません
move.w #$1300,d0 * minus(特別)
Not:
movea.l (a4),a0
move.w d0,(a0)+ * 式(演算子)
move.l a0,(a4)
解釈loop:
* まず、空白(9,32)を飛ばして、先頭の文字を見る。
bsr first_check_a5_in_line
* 数字なら d0 = 0
* 行の終わりなら d0 = -1
* その他なら d0 = そのキャラクタ
tst.w d0
beq 数字
bmi 式err
cmpi.b #'.',d0
beq 数字
cmpi.b #'&',d0
beq 型付き数字
cmpi.b #'"',d0
beq str定数
cmpi.b #$27,d0 * 「 ' 」
beq 一文字定数
* 括弧がついてるかどうか調べなければ
cmpi.b #'(',d0
bne 括弧無し
addq.l #1,a5
move.l 8(a4),a3
moveq #-1,d2
bsr math解釈 **** 再帰 ****
movem.l (a4),a0-a2
* a1 = 項のアドレスを並べるポインタ
* a2 = 項を並べるポインタ
clr.w (a0)+ * 式
move.l a2,(a1)+
adda.l d0,a2 * 項
lsr.l #1,d0
move.l d0,(a1)+ * 長さ
movem.l a0-a2,(a4)
cmpi.b #')',(a5)+ * 括弧がちゃんと終わっているか?
beq 演算子チェック
bra 式err
括弧無し:
* ハッシュ値を計算しながら、文字数を数える
bsr hash
* a2.l = 元の対象の開始アドレス
* d5.w = ハッシュ値だ。上位バイトもそのままだ
* d4.w = 文字数 - 1
* d1.b = お次の文字 ( (,[,=,:, , etc... )
tst.w d4
blt 式err
* 関数かどうかチェック
cmpi.b #'(',d1
bne 変数かどうかチェック
* d4.l = * (hash.w)(文字数-1)
* a2.l = 元の対象の開始アドレス
bsr function_check
* d0.w = ヒットした関数の返り値の型 ( = 0 : 該当関数無し )
* = $8000 float
* = $8001 int
* = $8003 str
* = $ffff void
* d0.w < 0 の時
* d1.w = 引き数の個数
* d3.w = 0 から始まる関数番号 ( < 0 : 内部関数になる予定 )
* a2 = パラメーターテーブル
tst.w d0
beq 変数かどうかチェック
tst.b d0
bmi void呼出
beq float呼出
subq.b #1,d0
beq int呼出
subq.b #1,d0
beq char呼出
*str呼出:
move.w #$c001,d2
bra @f
float呼出:
move.w #$c080,d2
bra @f
char呼出:
move.w #$c002,d2
bra @f
int呼出:
move.w #$c000,d2 * int 関数を示す
@@:
* 関数の処理
movem.l (a4),a0-a1/a3
* a1 = 項のアドレスを並べるポインタ
* a3 = 項を並べるポインタ
clr.w (a0)+ * 式
move.l a3,(a1)+
move.w d2,(a3)+ * 関数印+型
* 関数の解釈
* input a2 = パラメーターテーブル
* a3 = 書き込み先アドレス
* d1.w = 引き数の個数
* d3.w = 0 から始まる関数番号 ( < 0 : 内部関数になる予定 )
movem.l d4-d6/a0-a1/a4,-(sp)
bsr function解釈
movem.l (sp)+,d4-d6/a0-a1/a4
* d0 = 書き込んだ長さ
addq.l #2,d0
lsr.l #1,d0 * ワード単位
move.l d0,(a1)+
movem.l a0-a1/a3,(a4)
bra 演算子チェック
void呼出:
ERRORS 21
変数かどうかチェック:
* 変数かどうかチェック
* d4.l = * (hash.w)(文字数-1)
* a2.l = 元の対象の開始アドレス
bsr variable_check
* 重なってない d2.l = -1
* int の n 番と一致 d2.l = n+0000 ( n < システム変数 )
* str の n 番と一致 d2.l = n+0100 ( n < システム変数 )
* char の n 番と一致 d2.l = n+0200
* float の n 番と一致 d2.l = n+8000
* d2.l < 0 = 代入出来ない(当たりがない or system 変数)
* d0 = 0 : 普通の変数
* 1 : 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* $80 : auto 変数
* $81 : auto 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* -1 : 当たりなし
bmi misengen_var
cmpi.w #$0100,d2
bne @f
cmpi.b #'[',(a5)
beq 文字列ポインタ
@@:
btst #0,d0
beq 普通の変数参照
* 配列の場合
move.l (a4),a1
clr.w (a1)+ * 式
move.l a1,(a4)
movem.l 4(a4),a1-a2
* a1 = 項のアドレスを並べるポインタ
* a2 = 項を並べるポインタ
move.l a2,(a1)+
* a0 = その配列情報
addq.l #8,a0
move.w (a0)+,d2 * 型 ($0000,$0100,$0200,$8000)
move.b #$60,d2 * 配列を示す
tst.b d0
bpl @f
addq.b #1,d2
@@:
ror.w #8,d2
swap d2
move.l d2,(a2)+ * [配列の印 + 型] + 配列番号
* move.w d1,(a2)+ *
move.w (a0)+,d2 * 次元 - 1
cmpi.b #'(',(a5)
bne 式err
moveq #0,d0 * 添え字情報の長さ
@@:
addq.l #1,a5
movea.l a2,a3
movem.l d0/d2/d6/a0-a1,-(sp)
moveq #0,d2 * int
bsr math解釈 **** 再帰 ****
add.l (sp)+,d0
movem.l (sp)+,d2/d6/a0-a1
movea.l a3,a2 * 項
cmpi.b #',',(a5)
dbne d2,@b
beq 添え字の個数が多い
tst.w d2
bne 添え字の個数が少ない
cmpi.b #')',(a5)+ * 括弧がちゃんと終わっているか?
bne 式err
lsr.l #1,d0
addq.l #4/2,d0
move.l d0,(a1)+ * 長さ
movem.l a1-a2,4(a4)
bra 演算子チェック
添え字の個数が少ない:
ERROR 56
添え字の個数が多い:
ERROR 57
普通の変数参照:
movem.l (a4),a0-a2
clr.w (a0)+ * 式
* a1 = 項のアドレスを並べるポインタ
* a2 = 項を並べるポインタ
move.l a2,(a1)+
move.b #$40,d2 * 変数を示す
tst.b d0
bpl @f
addq.b #1,d2
@@:
ror.w #8,d2
swap d2
move.l d2,(a2)+
moveq #4/2,d0
move.l d0,(a1)+
movem.l a0-a2,(a4)
bra 演算子チェック
文字列ポインタ:
addq.l #1,a5
btst #0,d0
bne 式err * 配列だって?
tst.l d2
bmi 式err * system変数?
move.w #$0200,d2 * char
* 型(d6) <- 型(d2) の代入が整合しているかどうか
* bsr 型check
move.w #$5002,d2
tst.b d0
bge @f
move.w #$5102,d2
@@:
movem.l (a4),a0-a2
* a1 = 項のアドレスを並べるポインタ
* a2 = 項を並べるポインタ
clr.w (a0)+ * 式
move.l a2,(a1)+
move.w d2,(a2)+ * 文字列変数ポインタ
swap d2
move.w d2,-(sp)
movea.l a2,a3
movem.l a0-a1,-(sp)
moveq #0,d2 * int
bsr math解釈 **** 再帰 ****
movem.l (sp)+,a0-a1
movea.l a3,a2
move.w (sp)+,(a2)+ * 変数番号
cmpi.b #']',(a5)+ * 括弧がちゃんと終わっているか?
bne 式err
lsr.l #1,d0
addq.l #4/2,d0
move.l d0,(a1)+ * 長さ
movem.l a0-a2,(a4)
bra 演算子チェック
str定数:
movem.l (a4),a0-a2
* a1 = 項のアドレスを並べるポインタ
* a2 = 項を並べるポインタ
clr.w (a0)+ * 式
move.l a2,(a1)+
move.w #$8001,(a2)+ * 文字列定数を示す
* (a5)"~" を (a2) に書き移す
bsr str_copy
* a2 = 次の偶数アドレス
* d0 = データの長さ / 2
addq.l #1,d0
move.l d0,(a1)+ * 項の長さ
movem.l a0-a2,(a4)
bra 演算子チェック
一文字定数:
addq.l #1,a5
moveq.l #0,d0
move.b (a5)+,d0
cmpi.b #$27,(a5)+ * 「 ' 」
bne 式err
moveq #INT,d2
movem.l (a4),a0-a2
* a1 = 項のアドレスを並べるポインタ
* a2 = 項を並べるポインタ
clr.w (a0)+ * 式
move.l a2,(a1)+
moveq #6/2,d1
move.l d1,(a1)+ * 項の長さ
move.w #$8000,(a2)+ * 定数を示す
move.l d0,(a2)+ * int
movem.l a0-a2,(a4)
bra 演算子チェック
型付き数字:
moveq #INT,d2
bra @f
数字:
bsr Imm判断 * d2 = 小数点があれば float 型、でなければ int 型
@@:
bsr 定数get
movem.l (a4),a0-a2
* a1 = 項のアドレスを並べるポインタ
* a2 = 項を並べるポインタ
clr.w (a0)+ * 式
move.l a2,(a1)+
move.w d2,d3
move.b #$80,d3 * 定数を示す
ror.w #8,d3
move.w d3,(a2)+
cmpi.w #FLOAT,d2
beq __float
* FPACK __DTOL * (符号)(絶対値の整数化)を取るやつ
move.l d0,(a2)+ * int
moveq #6/2,d0
bra @f
__float
move.l d0,(a2)+ * float の上位ロングワード
move.l d1,(a2)+ * float の下位ロングワード
moveq #10/2,d0
cmpi.b #'#',(a5)
bne @f
addq.l #1,a5
@@:
move.l d0,(a1)+ * 項の長さ
movem.l a0-a2,(a4)
*** bra 演算子チェック *
演算子チェック:
* 演算子チェック
bsr cal_check
* 演算子だったら d0.w = 演算子番号+優先順位
* 違ったら d0.w = 0
* プログラム終了なら d0.w = -1
tst.w d0
ble 並べ替え * 数式コード化終了
cmpi.w #$0f10,d0 * 'not'
beq 式err
movea.l (a4),a0
move.w d0,(a0)+ * siki
move.l a0,(a4)
bra 解釈
** ** **
並べ替え:
movea.l (a4),a1
move.l a1,d4
sub.l a4,d4
lsr.w #1,d4
subi.w #9,d4
move.w d4,-(sp) * 保存 (式要素数-1)
subq.w #1,d4
bcs 展開
並べ替えloop:
move.w -(a1),d2
ble 並べ替えcont
cmpi.w #$0f10,d2 * 'not'
beq 並べ替えcont
cmpi.w #$1300,d2 * minus
beq 並べ替えcont
movea.l a1,a0
move.w d4,d3
移動loop:
move.w -(a0),d1
beq @f * 項は無条件でずれる
bmi 移動終了 * 移動後のものは抜かさない
cmp.b d2,d1 * 優先順位比較
bhi 移動終了
@@:
move.w d1,2(a0)
dbra d3,移動loop
subq.l #2,a0
移動終了:
bset #15,d2 * もう動かない
move.w d2,2(a0)
並べ替えcont:
dbra d4,並べ替えloop
展開:
move.w (sp)+,d5
lea.l $100(a4),a1
lea.l $10(a4),a2
move.l $c(a4),a3
bsr 最適化 *
lsl.w #8,d0
move.l (sp)+,d6
cmpi.w #$ffff,d6
bne @f
move.w d0,d6
bra 1f
@@:
cmp.w d0,d6
beq 1f
cmpi.w #STR,d0
beq 型違い
cmpi.w #STR,d6
beq 型違い
1:
moveq #0,d0
展開loop:
move.w (a2)+,d1
cmpi.w #$100,d1
bcc 演算子だ
lsl.w #3,d1
movea.l (a1,d1.w),a0 * その項の内容のアドレス
move.l 4(a1,d1.w),d1 * その項の長さ (単位・ワード)
add.w d1,d0
subq.w #1,d1
@@:
move.w (a0)+,(a3)+
dbra d1,@b
bra 展開cont
演算子だ:
clr.w d2
move.b d1,d2
move.w d2,(a3)+ * 演算子だ+型
lsr.w #8,d1
add.w d1,d1
move.w d1,(a3)+ * 演算子番号 * 2
addq.w #2,d0 * 長さ (単位・ワード)
展開cont:
dbra d5,展開loop
add.w d0,d0 * 長さ (単位・バイト)
lea.l $400(sp),sp
move.l (sp)+,a4
rts
misengen_var:
ERRORS 7
式err:
ERROR 9
最適化:
movem.l d2/d4/a1-a3,-(sp)
moveq #0,d0
move.w d5,d4 * 項の数
sai1:
tst.w (a2)+
bne @f
move.w d0,-2(a2) * 「値」に番号づけ
addq.w #1,d0
@@:
dbra d4,sai1
.xdef break5
break5:
move.w d5,d4 * 項の数
最適化loop:
move.w -(a2),d6 * 後ろから読んでいく(演算子「後づけ」状態)
cmpi.w #$100,d6
bcc 最適化_演算子
最適化_値:
move.w d6,d1
lsl.w #3,d1
movea.l (a1,d1.w),a0 * その項の内容のアドレス
cmpi.b #$80,(a0)+
beq 1f
moveq #-1,d6 * 定数でない
bra @f
1:
lsl.w #8,d6
@@:
move.b (a0),d6
move.w d6,-(sp) * スタックに積む (値番号(<0:定数でない)、型)
bra 最適化cont
最適化_演算子:
bclr #15,d6 * 移動済み印がついてるかも
move.w d6,d2
lsr.w #8,d2 * 演算子番号
cmpi.w #$0f,d2 * not
beq 一項演算子
cmpi.w #$13,d2 * minus
beq 一項演算子
二項演算子:
move.w (sp)+,d0 * 前
move.w (sp),d1 * 後
cmpi.b #1,d0 * STR
bne @f
cmpi.b #1,d1 * STR
beq 二項STR
bra 型違い
@@:
move.b d0,d3
cmp.b d1,d0
beq 1f * 型一致
cmpi.b #1,d1 * STR
beq 型違い
tst.b d0 * float
bmi 1f
tst.b d1 * float
bmi 2f
clr.b d0
clr.b d3
bra 1f
2:
move.b d1,d3
1:
move.b d3,d6 * 型
move.b d3,1(sp)
cmpi.w #3,d2 * \
beq 3f
cmpi.w #4,d2 * mod
beq 3f
cmpi.w #7,d2
bcs @f
3:
clr.b d6 * int型専用の演算子
move.w #$ff00,(sp) * (定数でない、int 型)
* clr.w 1(sp)
@@:
move.w d6,(a2) * 型登録
* bra 最適化cont
tst.w d1
bmi @f
tst.w d0
bmi 後ろは定数である
* 両方とも定数
tst.b d0
bmi 二項定数float
tst.b d1
bmi 二項定数float
bra 二項定数int
@@:
tst.w d0
bmi 両方は定数でない
前は定数である:
tst.b d0
bmi 両方は定数でない
tst.b d1
bmi 両方は定数でない
* とりあえず両方 int の時のみ
move.w d0,d1
cmpi.w #1,d2 * *
beq 掛け算片方
cmpi.w #5,d2 * +
beq 足し算片方
bra 両方は定数でない
後ろは定数である:
tst.b d0
bmi 両方は定数でない
tst.b d1
bmi 両方は定数でない
* とりあえず両方 int の時のみ
subq.w #8,d2
bhi 両方は定数でない
add.w d2,d2
move.w _s(pc,d2.w),d2
jmp _s(pc,d2.w)
.dc.w 両方は定数でない-_s
.dc.w 掛け算片方-_s
.dc.w 割り算片方-_s
.dc.w 割り算片方-_s
.dc.w 両方は定数でない-_s
.dc.w 足し算片方-_s
.dc.w 引き算片方-_s
.dc.w SHR片方-_s
_s: .dc.w SHL片方-_s
SHL片方:
lsr.w #8,d1
move.w d1,d0 * #
lsl.w #3,d0
movea.l (a1,d0.w),a0
move.l 2(a0),d0 * 第二項
beq 両方は定数でない
subq.l #8,d0
bhi 両方は定数でない
add.w d0,d0
move.w _shl(pc,d0.w),d0
bra 9f
.dc.w $30 *2
.dc.w $32 *4
.dc.w $36 *8
.dc.w $3e *16
.dc.w $40 *32
.dc.w $41
.dc.w $42
_shl: .dc.w $43
SHR片方:
lsr.w #8,d1
move.w d1,d0 * #
lsl.w #3,d0
movea.l (a1,d0.w),a0
move.l 2(a0),d0 * 第二項
beq 両方は定数でない
subq.l #8,d0
bhi 両方は定数でない
add.w #$50-1+8,d0 * $50~$57
bra 9f
引き算片方:
lsr.w #8,d1
move.w d1,d0 * #
lsl.w #3,d0
movea.l (a1,d0.w),a0
move.l 2(a0),d0 * 第二項
beq 両方は定数でない * あとで
subq.l #8,d0
bhi 両方は定数でない
add.w #$28-1+8,d0 * $28~$2f
bra 9f
割り算片方:
lsr.w #8,d1
move.w d1,d0 * #
lsl.w #3,d0
movea.l (a1,d0.w),a0
move.l 2(a0),d0 * 第二項
lsr.l #1,d0 * H8/2/1 thanks for 村重さん
bcs 両方は定数でない
beq 式err * 0で割れんよ
moveq #$48,d2
.rept 7
lsr.w #1,d0
bcs @f
addq.w #1,d2
.endm
lsr.w #1,d0
bcc 両方は定数でない
@@:
tst.l d0
bne 両方は定数でない
move.w d2,d0
bra 9f
掛け算片方:
lsr.w #8,d1
move.w d1,d0 * #
lsl.w #3,d0
movea.l (a1,d0.w),a0
move.l 2(a0),d0 * 第二項
subq.l #2,d0
bcs 両方は定数でない * 0,1 は無視
cmpi.l #16-2,d0
bhi @f
add.w #$30,d0 * $30~$3e
bra 9f
@@:
cmpi.l #32-2,d0
beq mul32
cmpi.l #64-2,d0
beq mul64
cmpi.l #128-2,d0
beq mul128
cmpi.l #256-2,d0
beq mul256
bra 両方は定数でない
mul32:
move.w #$40,d0
bra 9f
mul64:
move.w #$41,d0
bra 9f
mul128:
move.w #$42,d0
bra 9f
mul256:
move.w #$43,d0
bra 9f
足し算片方:
lsr.w #8,d1
move.w d1,d0 * #
lsl.w #3,d0
movea.l (a1,d0.w),a0
move.l 2(a0),d0 * 第二項
beq 両方は定数でない * あとで
subq.l #8,d0
bhi 両方は定数でない
add.w #$1f+8,d0 * $20~$27
9:
lsl.w #8,d0
move.w d0,(a2) * 'addq.l d0,??' の演算子(int)
move.w #$ff00,(sp) * (定数でない、int 型)
subq.w #1,d5
move.w d5,d0
sub.w d4,d0
movea.l a2,a0
@@:
cmp.w (a0)+,d1
dbeq d0,@b
bne 最適化cont
subq.l #2,a0
@@:
move.w 2(a0),(a0)+
dbra d0,@b
bra 最適化cont
二項定数float演算しない:
move.w #$ff80,(sp) * (定数でない、float 型)
bra 最適化cont
二項定数float:
cmpi.w #3,d2 * \
beq 二項定数float演算しない
cmpi.w #4,d2 * mod
beq 二項定数float演算しない
cmpi.w #7,d2 * sh? 関係・論理
bcc 二項定数float演算しない
tst.b d0
bge @f
move.w d0,(sp) * float登録
* (d0 がfloat でないなら、すでに登録されているd1がfloat)
@@:
movem.w d0/d2,-(sp)
lsr.w #8,d1
bcc 第二項int
lsl.w #3,d1
movea.l (a1,d1.w),a0
movem.l 2(a0),d2-d3 * 第二項
bra @f
第二項int:
lsl.w #3,d1
movea.l (a1,d1.w),a0
move.l 2(a0),d0 * 第二項
FPACK __LTOD
move.l d0,d2
move.l d1,d3
@@:
move.w (sp)+,d0
lsr.w #8,d0
bcc 第一項int
lsl.w #3,d0
movea.l (a1,d0.w),a0
movem.l 2(a0),d0-d1 * 第一項
bra @f
第一項int:
lsl.w #3,d0
movea.l (a1,d0.w),a0
move.l 2(a0),d0 * 第一項
FPACK __LTOD
@@:
move.w (sp)+,d6
add.w d6,d6 * 演算子番号
move.w saf(pc,d6.w),d6
jmp saf(pc,d6.w)
saf:
.dc.w 0 * dummy
.dc.w Sfmul-saf
.dc.w Sfdiv-saf
.dc.w 0
.dc.w 0
.dc.w Sfadd-saf
.dc.w Sfsub-saf
Sfmul:
FPACK __DMUL
bra @f
Sfdiv:
FPACK __DDIV
bra @f
Sfadd:
FPACK __DADD
bra @f
Sfsub:
FPACK __DSUB
@@:
move.w (sp),d2
lsr.w #8,d2
move.w d2,4(a2) * だんだんよくわからなくなってきた。
lsl.w #3,d2
movea.l (a1,d2.w),a0
movem.l d0-d1,2(a0)
bra 2ずらしf
* 両方ともint定数
二項定数int:
lsr.w #8,d0
lsl.w #3,d0
movea.l (a1,d0.w),a0
addq.l #2,a0
move.l (a0),d0 * 第一項
lsr.w #8,d1
lsl.w #3,d1
movea.l (a1,d1.w),a0
addq.l #2,a0
move.l (a0),d1 * 第二項
add.w d2,d2 * 演算子番号
move.w sai(pc,d2.w),d2
jmp sai(pc,d2.w)
sai:
.dc.w 0 * dummy
.dc.w Smul-sai
.dc.w Sdiv-sai
.dc.w Sdiv2-sai
.dc.w Smod-sai
.dc.w Sadd-sai
.dc.w Ssub-sai
.dc.w Sshr-sai
.dc.w Sshl-sai
.dc.w Sequal-sai
.dc.w Snoteq-sai
.dc.w Ssmall-sai
.dc.w Slarge-sai
.dc.w Seq_small-sai
.dc.w Seq_large-sai
.dc.w 0 * Snot-sai
.dc.w Sand-sai
.dc.w Sor-sai
.dc.w Sxor-sai
* .dc.w Sminus-sai
Smul:
FPACK __LMUL
bra 2ずらし
Sdiv:
Sdiv2:
FPACK __LDIV
bra 2ずらし
Smod:
FPACK __LMOD
bra 2ずらし
Sadd:
add.l d1,d0
bra 2ずらし
Ssub:
sub.l d1,d0
bra 2ずらし
Sshr:
lsr.l d1,d0
bra 2ずらし
Sshl:
lsl.l d1,d0
bra 2ずらし
Sequal:
cmp.l d1,d0
beq Strue
bra Sfault
Snoteq:
cmp.l d1,d0
bne Strue
bra Sfault
Ssmall:
cmp.l d1,d0
blt Strue
bra Sfault
Slarge:
cmp.l d1,d0
bgt Strue
bra Sfault
Seq_small:
cmp.l d1,d0
ble Strue
bra Sfault
Seq_large:
cmp.l d1,d0
bge Strue
bra Sfault
Sfault:
moveq #0,d0
bra 2ずらし
Strue:
moveq #-1,d0
bra 2ずらし
Sand:
and.l d1,d0
bra 2ずらし
Sor:
or.l d1,d0
bra 2ずらし
Sxor:
eor.l d1,d0
* bra 2ずらし
2ずらし:
move.l d0,(a0) * 後ろの項に化ける
2ずらしf:
subq.w #2,d5
move.w d5,d0
sub.w d4,d0
movea.l a2,a0
@@:
move.w 4(a0),(a0)+
dbra d0,@b
bra 最適化cont
両方は定数でない:
move.b #$ff,(sp) * 定数でない
bra 最適化cont
二項STR:
move.b d0,d6 * 型
cmpi.w #5,d2 * '+'
bne 二項STR2
move.w d6,(a2) * 登録
bra 最適化cont
二項STR2:
cmpi.w #9,d2
bcs 型違い
cmpi.w #$0f,d2
bcc 型違い
clr.b d6 * int型
move.w d6,(a2) * 登録
move.w #$ff00,(sp) * (定数でない、int 型)
bra 最適化cont
一項演算子:
move.w (sp),d0 * スタックから取り出す
cmpi.b #1,d0 * STR
beq 型違い
tst.b d0
bmi @f * float
tst.w d0
bge 一項定数
@@:
cmpi.w #$0f,d2 * not
beq 一項not
一項minus:
move.b d0,d6 * 型
move.w d6,(a2) * 登録
bra 最適化cont
一項not:
clr.b d6 * int 型
move.w d6,(a2) * 登録
bra 最適化cont
一項定数:
lsr.w #8,d0 * 値番号
lsl.w #3,d0
movea.l (a1,d0.w),a0 * その項の内容のアドレス
addq.l #2,a0
move.l (a0),d0
cmpi.w #$0f,d2 * not
bne @f
not.l d0
bra 1ずらし
@@:
neg.l d0
1ずらし:
move.l d0,(a0) * 後ろの項に化ける
subq.w #1,d5
move.w d5,d0
sub.w d4,d0
movea.l a2,a0
@@:
move.w 2(a0),(a0)+
dbra d0,@b
* bra 最適化cont
最適化cont:
dbra d4,最適化loop
move.w (sp)+,d0 * スタックから出す
*最適化しない:
movem.l (sp)+,d2/d4/a1-a3
rts
定数get:
cmpi.w #FLOAT,d2
beq 定数float
cmpi.b #'&',(a5)
beq 定数etc
movea.l a5,a0
FPACK __STOL
movea.l a0,a5
rts
定数etc:
lea.l 1(a5),a0
moveq #$20,d0
or.b (a0)+,d0
cmpi.b #'h',d0
beq 定数HEX
cmpi.b #'b',d0
beq 定数BIN
cmpi.b #'o',d0
beq 定数OCT
bra 式err
定数BIN:
FPACK __STOB
movea.l a0,a5
rts
定数OCT:
FPACK __STOO
movea.l a0,a5
rts
定数HEX:
FPACK __STOH
movea.l a0,a5
rts
定数float:
move.w d2,-(sp)
movea.l a5,a0
FPACK __VAL * 数値変換
movea.l a0,a5
move.w (sp)+,d2
rts
Imm判断: * (a5) 小数点 or '#' があれば float 型、でなければ int 型
movea.l a5,a0
im_loop:
move.b (a0)+,d2
beq int判定
cmpi.b #'.',d2
beq float判定
cmpi.b #'#',d2
beq float判定
cmpi.b #'9',d2
bhi int判定
cmpi.b #'0',d2
bcc im_loop
int判定:
moveq #INT,d2
rts
float判定:
move.w #FLOAT,d2
rts
* (a5)"~" を (a2) に書き移す
str_copy:
* a2 = 次の偶数アドレス
* d0 = データの長さ / 2
addq.l #1,a5 * '"'
moveq #0+1,d0 * 最後の $00 の文
sc_loop:
move.b (a5)+,d1
beq sc_end
cmpi.b #'"',d1
bhi sc_ok
beq sc_end0
cmpi.b #$d,d1
beq sc_end
cmpi.b #$a,d1
beq sc_end
sc_ok:
move.b d1,(a2)+
addq.w #1,d0
bra sc_loop
sc_end:
subq.l #1,a5 * $00,$0a,$0d
sc_end0:
clr.b (a2)+
lsr.w #1,d0
bcc @f
addq.w #1,d0
clr.b (a2)+ * even
@@:
rts
** ** ** ** ** ** ** ** **
* 関数の解釈
* input a2 = パラメーターテーブル
* a3 = 書き込み先アドレス
* d1.w = 引き数の個数
* d3.w = 0 から始まる関数番号 ( < 0 : 内部関数になる予定 )
.xdef function解釈
function解釈:
* d0 = 書き込んだ長さ
movem.l d4-d6,-(sp)
* move.w d3,(a3)+ * d3.w = 0 から始まる関数番号
move.w d3,-(sp) * d3.w = 0 から始まる関数番号
move.w d1,(a3)+ * d1.w = 引き数の個数
moveq #4,d1 * 書き込んだ長さ
fnc_loop:
cmpi.b #')',(a5)
beq @f
addq.l #1,a5 * '(' or ','
@@:
* まず、空白(9,32)を飛ばして、先頭の文字を見る。
bsr first_check_a5_in_line
* 数字なら d0 = 0
* 行の終わりなら d0 = -1
* その他なら d0 = そのキャラクタ
move.w (a2)+,d2 * parameter get
bge @f
cmpi.w #$8080,d2 * 配列拡張
beq 拡張配列の引き数
bra fnc_loop_end * 返り値
@@:
tst.b d2
bge @f
* 省略可能な引き数
cmpi.b #',',d0
beq 引き数省略
cmpi.b #')',d0
beq 引き数省略
@@:
moveq #$60,d0
and.b d2,d0
bne 配列の引き数
btst #4,d2
bne ポインタの引き数
btst #0,d2
bne float引き数
btst #1,d2
bne int引き数
btst #2,d2
bne char引き数
btst #3,d2
bne str引き数
ERROR 19
float引き数:
move.w #$8080,d2
bra @f
char引き数:
move.w #$8002,d2
bra @f
str引き数:
move.w #$8001,d2
bra @f
int引き数:
move.w #$8000,d2
@@:
move.w d2,(a3)+
addq.w #2,d1
ror.w #8,d2
clr.b d2
* 解釈した結果を (a3) からに書き込み、その長さを d0.l に返す
* int d2.w = 0000
* str d2.w = 0100
* char d2.w = 0200
* float d2.w = 8000
* 型未判明 d2.w = ffff
movem.l d1/a2,-(sp)
bsr math解釈
movem.l (sp)+,d1/a2
* return d6.w = 変数の型
add.l d0,d1
bra fnc_loop
引き数省略:
move.w #$00ff,(a3)+
addq.w #2,d1
bra fnc_loop
* d0.b = $20 1次元配列
* d0.b = $40 2次元配列
配列の引き数:
movem.l d1/a2/a3,-(sp)
movem.w d0/d2,-(sp)
bsr hash
tst.w d4
blt hennahikisu
* d4.l = * (hash.w)(文字数-1)
* a2.l = 元の対象の開始アドレス
bsr variable_check
* 重なってない d2.l = -1
* int の n 番と一致 d2.l = n+0000 ( n < システム変数 )
* str の n 番と一致 d2.l = n+0100 ( n < システム変数 )
* char の n 番と一致 d2.l = n+0200
* float の n 番と一致 d2.l = n+8000
* d2.l < 0 = 代入出来ない(当たりがない or system 変数)
* d0 = 0 : 普通の変数
* 1 : 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* $80 : auto 変数
* $81 : auto 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* -1 : 当たりなし
bmi hennahikisu
btst #0,d0
beq hennahikisu
move.b d0,d3
move.w (sp)+,d0 * 要求している次元
move.w $a(a0),d1 * 指定された配列の次元
beq @f
subq.w #1,d1
bne hennahikisu * 3次元以上の配列は駄目
btst #6,d0
bne fnc_1
bra hennahikisu
@@:
btst #5,d0
beq hennahikisu
fnc_1
move.w (sp)+,d0 * 引き数の型
movem.l (sp)+,d1/a2/a3
bsr 引き数型check
move.b #$40,d2 * 配列の引き数
tst.b d3
bpl @f
addq.b #1,d2 * auto 配列の引き数
@@:
ror.w #8,d2
swap d2 * 下位=配列番号
move.l d2,(a3)+
addq.w #4,d1
bra fnc_loop
拡張配列の引き数:
movem.l d1/a2/a3,-(sp)
bsr hash
tst.w d4
blt hennahikisu
* d4.l = * (hash.w)(文字数-1)
* a2.l = 元の対象の開始アドレス
bsr variable_check
* 重なってない d2.l = -1
* int の n 番と一致 d2.l = n+0000 ( n < システム変数 )
* str の n 番と一致 d2.l = n+0100 ( n < システム変数 )
* char の n 番と一致 d2.l = n+0200
* float の n 番と一致 d2.l = n+8000
* d2.l < 0 = 代入出来ない(当たりがない or system 変数)
* d0 = 0 : 普通の変数
* 1 : 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* $80 : auto 変数
* $81 : auto 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* -1 : 当たりなし
bmi hennahikisu * 未宣言
btst #0,d0 * 配列
beq hennahikisu
movem.l (sp)+,d1/a2/a3
move.w (a2)+,d4 * 型+次元-1
moveq #$f,d3
and.w d4,d3 * 次元-1
clr.b d4 * 型
cmp.w d2,d4
bne hennahikisu * 型が合わない
cmp.w $a(a0),d3
bne dim_jigen * 次元が合わない
move.b #$40,d2 * 配列の引き数
tst.b d0
bpl @f
addq.b #1,d2 * auto 配列の引き数
@@:
ror.w #8,d2
swap d2 * 下位=配列番号
move.l d2,(a3)+
addq.w #4,d1
move.w (a2)+,d4 * 添字指定フラグ
lea.l 12(a0),a0 * その配列の添字列
1:
add.w d4,d4
bcc @f
move.w (a2),d0 * 添字指定の大きさ(あれば)
cmp.w (a0),d0
bne dim_soeji * 添字が合わない
@@:
addq.l #2,a0
addq.l #2,a2
dbra d3,1b
bra fnc_loop
ポインタの引き数:
* ということは、必ず「代入出来る」変数名を指定してるはずだ
move.w d2,-(sp)
movem.l d1/a2/a3,-(sp)
bsr hash
tst.w d4
blt hennahikisu
* d4.l = * (hash.w)(文字数-1)
* a2.l = 元の対象の開始アドレス
bsr variable_check
movem.l (sp)+,d1/a2/a3
* 重なってない d2.l = -1
* int の n 番と一致 d2.l = n+0000 ( n < システム変数 )
* str の n 番と一致 d2.l = n+0100 ( n < システム変数 )
* char の n 番と一致 d2.l = n+0200
* float の n 番と一致 d2.l = n+8000
* d2.l < 0 = 代入出来ない(当たりがない or system 変数)
* d0 = 0 : 普通の変数
* 1 : 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* $80 : auto 変数
* $81 : auto 配列 ( a0 = その配列情報のポインタ , d1 = 添え字の最大数 )
* -1 : 当たりなし
tst.l d2
bmi hennahikisu
btst #0,d0
bne hennahikisu
move.b d0,d3
move.w (sp)+,d0 * 引き数の型
bsr 引き数型check
move.b #$60,d2 * ポインタの引き数
tst.b d3
bpl @f
addq.b #1,d2 * auto 変数のポインタの引き数
@@:
ror.w #8,d2
swap d2 * 下位=変数番号
move.l d2,(a3)+
addq.w #4,d1
bra fnc_loop
fnc_loop_end:
cmpi.b #')',d0
bne fnc_err
addq.l #1,a5
move.w (sp)+,(a3)+ * 0 から始まる関数番号
move.l d1,d0
movem.l (sp)+,d4-d6
rts
* X-BASIC format の型指定と、ぺけBのが一致するかどうか
引き数型check:
btst #0,d0
beq @f
cmpi.w #$8000,d2
beq arg_check_ok
@@:
btst #1,d0
beq @f
tst.w d2
beq arg_check_ok
@@:
btst #2,d0
beq @f
cmpi.w #$0200,d2
beq arg_check_ok
@@:
btst #3,d0
beq @f
cmpi.w #$0100,d2
beq arg_check_ok
@@:
hennahikisu:
ERROR 18
arg_check_ok:
rts
dim_soeji:
ERROR 74
dim_jigen:
ERROR 75
fnc_err:
ERROR 16
型違い:
ERROR 31
.end